﻿using System.Collections.Generic;
using System.IO;

using System.Xml;
using System.Xml.Linq;

using System.Xml.Schema;

namespace MockingBird.Common.Infrastructure.Validation
{
    /// <summary>
    /// This class validates a given xml file against a given xsd file
    /// </summary>
    public static class SchemaValidator
    {
        private static List<string> validationErrors = new List<string>();
        private static int errorCount = 0;

        #region "Properties"
        public static int ErrorCount
        {
            get
            {
                return errorCount;
            }
        }
        public static List<string> ValidationErrors
        {
            get
            {
                return validationErrors;
            }
        }
        #endregion

        #region "public methods"
        public static bool ValidateXml(string xmlFileName, string xsdFileName)
        {
            ResetErrors();
            string xml;
            using (StringReader sr = new StringReader(xmlFileName))
            {
                xml = sr.ReadToEnd();
            }

            XDocument xDoc = new XDocument(xml);
            return ValidateXml(xDoc, xsdFileName);
        }

        public static bool ValidateXml(XDocument xDoc, string xsdFileName)
        {
            //reset the errors because this is a static class
            ResetErrors();

            XmlSchemaSet schemaSet = LoadSchema(xsdFileName);
            xDoc.Validate(schemaSet, ErrorHandler);

            //TODO: remove this count, we can always get it from the List.Count property
            if (ErrorCount == 0)
                return true;
            else
                return false;
        }
        #endregion

        #region "Private methods"
        private static XmlSchemaSet LoadSchema(string schemaFileName)
        {
            XmlSchemaSet schemaSet = new XmlSchemaSet(new NameTable());
            using (XmlReader reader = XmlReader.Create(schemaFileName))
            {
                XmlSchema xsd = XmlSchema.Read(reader, null);
                reader.Close();
                schemaSet.Add(xsd);
            }

            return schemaSet;
        }

        private static void ErrorHandler(object sender, ValidationEventArgs args)
        {
            errorCount++;
            ValidationErrors.Add(args.Message);
        }

        private static void ResetErrors()
        {
            errorCount = 0;
            ValidationErrors.Clear();
        }

        #endregion

    }
}
